// Copyright 2011 Google Inc. All Rights Reserved.

package google.usingblobstore;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreInputStream;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Performs calculations on scores using Blobstore.
 * 
 * @author eschoeffler@google.com (Eric Schoeffler)
 */
public class BlobstoreScoreCalculator implements ScoreCalculator {

  private DatastoreService datastoreService;
  private BlobKey blobKey;
  
  public BlobstoreScoreCalculator() {
    datastoreService = DatastoreServiceFactory.getDatastoreService();
  }
  
  @Override
  public ScoresData averageByHair(String hairColor) {
    try {
      long start = System.currentTimeMillis();
      int count = 0;
      int totalScore = 0;
      for (Integer score : getScores(hairColor)) {
        count ++;
        totalScore += score;
      }
      long elapsed = System.currentTimeMillis() - start;
      return new ScoresData(elapsed / 1000.0, count, count == 0 ? 0 : totalScore / count);
    } catch (IOException e) {
    } catch (EntityNotFoundException e) {
    }
    return new ScoresData(0, 0, 0);
  }
  
  public List<Integer> getScores(String hairColor) throws IOException, EntityNotFoundException {
    Key personKey = KeyFactory.createKey("Blob", "people.csv");
    if (blobKey == null) {
      Entity blobInfo = datastoreService.get(personKey);
      blobKey = (BlobKey) blobInfo.getProperty("blob_info");
    }
    BufferedReader in = new BufferedReader(
        new InputStreamReader(new BlobstoreInputStream(blobKey)));
    
    List<Integer> scores = new ArrayList<Integer>();
    String line = in.readLine(); // ignore headers
    while((line = in.readLine()) != null) {
      String[] properties = line.split(",");
      if (hairColor == null || hairColor.trim().length() == 0 || properties[1].equals(hairColor)) {
        scores.add(Integer.parseInt(properties[2]));
      }
    }
    in.close();
    return scores;
  }

}
